package com.augurit.wf.common.web;

import java.io.InputStream;
import java.util.List;
import java.util.Map;

import org.apache.struts2.convention.annotation.ResultPath;
import org.jbpm.api.model.ActivityCoordinates;
import org.jbpm.api.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.FileCopyUtils;
import org.springside.modules.orm.Page;
import org.springside.modules.web.struts2.Struts2Utils;

import com.augurit.common.base.action.BaseAction;
import com.augurit.common.base.action.ExtBaseAction;
import com.augurit.common.base.extmodel.ExtResult;
import com.augurit.common.base.form.ResultForm;
import com.augurit.common.util.ExtUtils;
import com.augurit.common.util.lang.DateUtils;
import com.augurit.wf.bi.service.IWfBusTemplateService;
import com.augurit.wf.bi.service.IWfBusTemplateTypeService;
import com.augurit.wf.bi.service.IWfPageElementService;
import com.augurit.wf.bi.web.form.WfActElemPrivDefForm;
import com.augurit.wf.bi.web.form.WfBusInstanceTaskForm;
import com.augurit.wf.bi.web.form.WfBusTemplateForm;
import com.augurit.wf.bi.web.form.WfBusTemplateTypeForm;
import com.augurit.wf.bi.web.form.WfPageElementForm;
import com.augurit.wf.common.constant.MsgConstant;
import com.augurit.wf.common.form.TraceRecord;
import com.augurit.wf.common.service.IWfService;
import com.augurit.wf.common.util.ViewConfigCompiler;
import com.augurit.wf.common.util.WfUtils;
import com.augurit.wf.mgmt.service.IWfProcessInstanceService;
import com.augurit.wf.mgmt.web.form.WfActivityInstanceForm;

/**
 * 工作流Action类
 */
@SuppressWarnings("serial")
@ResultPath("/wf/client/common")
public class WfAction extends ExtBaseAction {

	//Service
	@Autowired
	private IWfBusTemplateService wfBusTemplateService;
	
	@Autowired
	private IWfBusTemplateTypeService wfBusTemplateTypeService;
	
	@Autowired
	private IWfPageElementService wfPageElementService;

	@Autowired
	private IWfService wfService;
	
	@Autowired
	private IWfProcessInstanceService wfProcessInstanceService;
	private Long actInstDbid;
	
	//属性
	private Page page = new Page();
	
	private WfActivityInstanceForm activityInstanceForm;//活动实例FORM
	private WfBusTemplateForm template = new WfBusTemplateForm();
	private WfBusInstanceTaskForm instance = new WfBusInstanceTaskForm();
	private Long[] taskInstDbids;	//用于批量签收

	private WfBusTemplateViewConfig viewConfig;
	
	private WfPageElementForm pageElement = new WfPageElementForm();
	
	private String loadProcessDiagramUrl;		//加载流程图的url
	
	private String forward;
	
	private List<WfBusTemplateTypeForm>  templateTypeList;
	
	public String portal() throws Exception {
		return getForward("portal");
	}
	
	public String wfDraft() throws Exception {
		template = wfBusTemplateService.getByTemplateCode(template.getTemplateCode());
		
		String wfDefId = WfUtils.convertToProcessDefinitionId(template.getWfDefKey(), template.getWfDefVersion());
		instance.setActivityName(wfService.getStartTaskActivityName(wfDefId));
		
		//设置流程定义ID
		instance.setProcessDefId(wfDefId);
		
		//设置流程实体的版本
		instance.setVersion(template.getWfDefVersion());
		return getForward("draft");
		
	}
	
	public String loadDbView() throws Exception {
		viewConfig = wfService.loadViewConfig(template.getTemplateCode());
		return getForward("db-tasks");
	}
	
	public String loadDbViewByTemplateId() throws Exception {
		template = wfBusTemplateService.get(template.getId());
		viewConfig = wfService.loadViewConfig(template.getTemplateCode());
		return getForward("db-tasks");
	}
	
	public String loadZbView() throws Exception {
		viewConfig = wfService.loadViewConfig(template.getTemplateCode());
		return getForward("zb-tasks");
	}
	
	public String loadDZbView() throws Exception {
		viewConfig = wfService.loadViewConfig(template.getTemplateCode());
		return getForward("dzb-tasks");
	}
	
	public String loadDZbViewByTemplateName() throws Exception {
		template = wfBusTemplateService.getByTemplateName(template.getTemplateName());
		viewConfig = wfService.loadViewConfig(template.getTemplateCode());
		return getForward("dzb-tasks");
	}
	
	public String loadYbView() throws Exception {
		viewConfig = wfService.loadViewConfig(template.getTemplateCode());
		BaseAction.getRequest().setAttribute("loginUserCode", this.getLoginUserName());
		BaseAction.getRequest().setAttribute("loginUserName", this.getLoginUser().getUser().getUserName());
		return getForward("yb-tasks");
	}
	
	public String loadBjView() throws Exception {
		viewConfig = wfService.loadViewConfig(template.getTemplateCode());
		return getForward("bj-tasks");
	}
	
	public String signTask() throws Exception {
		instance = wfService.getWfBusInstanceTaskById(instance.getTaskInstDbid(), this.getLoginUserName());
		instance.setViewName(WfActElemPrivDefForm.DB_ZB_VIEW);
		return getForward("sign-task");
	}
	
	public String viewTask() throws Exception {
		String viewName = instance.getViewName();
		instance = wfService.getWfBusInstanceById(instance.getWfBusInstanceId());
		instance.setVersion(wfService.getProcDefByProcInstId(instance.getProcInstId()).getVersion());
		instance.setViewName(viewName);
		instance.setActivityName(null);
		return getForward("view-task");
	}
	
//	/**
//	 * 查看流程图
//	 */
//	public String viewWfDiagram() throws Exception {
//		ActivityCoordinates coordinates = null;
//		if(instance.getProcInstId() != null){
//			coordinates = wfService.getActivityCoordinates(instance.getProcInstId());
//		}
//		else{
//			template = wfBusTemplateService.getByTemplateCode(template.getTemplateCode());
//			
//			String processDefinitionId = WfUtils.convertToProcessDefinitionId(template.getWfDefKey(), template.getWfDefVersion());
//			coordinates = wfService.getActivityCoordinates(processDefinitionId, instance.getActivityName());
//		}
//		
//		//把坐标信息写入request域
//		ExtBaseAction.getRequest().setAttribute("x_cord", coordinates.getX());
//		ExtBaseAction.getRequest().setAttribute("y_cord", coordinates.getY());
//		ExtBaseAction.getRequest().setAttribute("width", coordinates.getWidth());
//		ExtBaseAction.getRequest().setAttribute("height", coordinates.getHeight());
//		
//		loadProcessDiagramUrl = "/wf/common/wf!loadProcessDefPngFile.action?template.templateCode=" + template.getTemplateCode();
//		return getForward("view-proc-inst");
//	}
	
	/**
	 * 获取TaskOpinWin,加载jsp为了满足拖拉效果
	 */
//	public String getTaskOpinionWin() throws Exception{
//		if(instance.getTaskInstDbid() != null)
//			return getForward("opinion");
//		else
//			return null;
//	}
	
	public String getDbTasks() throws Exception {
		ExtUtils.initPageFromExtGridParam(this.getRequest(), page);
		Map<String, String> params = ViewConfigCompiler.convertToParamMap(this.getRequest().getParameterMap());
		wfService.loadDbTasksWithBusInfo(page, template.getTemplateCode(), this.getLoginUserName(), params);
		this.renderText(Struts2Utils.getJsonString(page, DateUtils.YYYY_MM_DD_HH_MM_SS));
		return null;
	}
	
	public String getDZbTasks() throws Exception {
		ExtUtils.initPageFromExtGridParam(this.getRequest(), page);
		Map<String, String> params = ViewConfigCompiler.convertToParamMap(this.getRequest().getParameterMap());
		wfService.loadDZbTasksWithBusInfo(page, template.getTemplateCode(), this.getLoginUserName(), params);
		this.renderText(Struts2Utils.getJsonString(page, DateUtils.YYYY_MM_DD_HH_MM_SS));
		return null;
	}
	
	public String takeTasks() throws Exception {
		wfService.takeTasks(taskInstDbids,this.getLoginUserName());
		this.extRenderSuccess();
		return null;
	}
	//任务领取视图
	public String loadCandidateView() throws Exception {
		viewConfig = wfService.loadViewConfig(template.getTemplateCode());
		return getForward("candidate-tasks");
	}
	
	/**
	 * 获取待领取任务列表
	 * @return
	 * @throws Exception
	 */
	public String getCandidateTasks() throws Exception{
		ExtUtils.initPageFromExtGridParam(this.getRequest(), page);
		Map<String, String> params = ViewConfigCompiler.convertToParamMap(this.getRequest().getParameterMap());
		wfService.loadCandidateTasksWithBusInfo(page, template.getTemplateCode(), this.getLoginUserName(), params);
		this.renderText(Struts2Utils.getJsonString(page, DateUtils.YYYY_MM_DD_HH_MM_SS));
		return null;
	}
	
	public String getZbTasks() throws Exception {
		ExtUtils.initPageFromExtGridParam(this.getRequest(), page);
		Map<String, String> params = ViewConfigCompiler.convertToParamMap(this.getRequest().getParameterMap());
		wfService.loadZbTasksWithBusInfo(page, template.getTemplateCode(), this.getLoginUserName(), params);
		this.renderText(Struts2Utils.getJsonString(page, DateUtils.YYYY_MM_DD_HH_MM_SS));
		return null;
	}
	
	public String getYbTasks() throws Exception {
		ExtUtils.initPageFromExtGridParam(WfAction.getRequest(), page);
		Map<String, String> params = ViewConfigCompiler.convertToParamMap(WfAction.getRequest().getParameterMap());
		wfService.loadYbTasksWithBusInfo(page, template.getTemplateCode(), this.getLoginUserName(), params);
		WfAction.extRenderGridJson(page);
		return null;
	}
	
	public String getBjTasks() throws Exception {
		ExtUtils.initPageFromExtGridParam(WfAction.getRequest(), page);
		Map<String, String> params = ViewConfigCompiler.convertToParamMap(WfAction.getRequest().getParameterMap());
		wfService.loadBjTasksWithBusInfo(page, template.getTemplateCode(), this.getLoginUserName(), params);
		WfAction.extRenderGridJson(page);
		return null;
	}

	public String signTasks() throws Exception {
		wfService.signTasks(taskInstDbids);
		WfAction.extRenderSuccess();
		return null;
	}
	
	/**
	 * 完成活动实例
	 * @param processInstanceId
	 * @param actInstId
	 */
	public String completeActInst()throws Exception{
		if(activityInstanceForm != null){
			//检测当前活动是处于活动状态
			boolean isSign = wfProcessInstanceService.isSign(activityInstanceForm.getExecutionId());
			if(!isSign){
				ResultForm result = new ResultForm(false,"当前活动实例不是处于活动状态，不能完成。");
				WfAction.renderJson(result);
				return null;
			}
			
			
			Long taskDbid = wfProcessInstanceService.getTaskByActInstDbid(activityInstanceForm.getDbid());
			if(taskDbid != null){
				instance.setTaskInstDbid(taskDbid);
				showWfSendWin();
			}else{
				WfAction.extRenderSuccess();
			}
		}
		return null;
	}

	/**
	 * 终止活动实例
	 * @param processInstanceId
	 * @param actInstId
	 */
	public String endActInst()throws Exception{
		List<Long> multitaskTaskIds = wfProcessInstanceService.getMultitaskTaskIdsBySuperTaskId(this.taskInstDbids[0]);
		wfProcessInstanceService.endActInst(multitaskTaskIds);
		return null;
	}
	
	/**
	 * 获取终止活动窗口信息
	 */
	@SuppressWarnings("unchecked")
	public String getEndActInstWinInfo()throws Exception{
		//检测当前活动是处于活动状态
		boolean isSign = wfProcessInstanceService.isSign(activityInstanceForm.getExecutionId());
		if(!isSign){
			ResultForm result = new ResultForm(false,"当前活动实例不是处于活动状态，不能终止。");
			WfAction.renderJson(result);
			return null;
		}
		
		//获取当前任务对象
		Task task = wfProcessInstanceService.getTaskIdByExecutionId(activityInstanceForm.getExecutionId(),activityInstanceForm.getDbid());
		
		if(task == null){
			WfAction.extRenderSuccess();
			return null;
		}
		
		instance.setTaskInstDbid(new Long(task.getId()));
		
		//根据任务是否为多任务去执行是否让用户选择路径
		if(WfUtils.isMultiTask(task)){
			ResultForm<WfBusInstanceTaskForm> resultForm = new ResultForm<WfBusInstanceTaskForm>(true,instance);
			WfAction.renderJson(resultForm);
		}else{
			showWfSendWin();
		}
		
		return null;
	}
	
	@SuppressWarnings("unchecked")
	public String showWfSendWin() throws Exception {
		wfService.loadWfSendOption(instance);
		
		if(instance.isDirectSend())
			wfSend();
        
		WfAction.renderJson(new ResultForm(false, instance));	//false表示不是直接发送，需要用户人工发送
		return null;
	}
	
	@SuppressWarnings("unchecked")
	public String wfSend() throws Exception {
		try {
			//先检测选择用户是否正确
			ResultForm result = wfService.validateSelectedAssignee(instance);
			
			if(result.isSuccess()){
				wfService.send(instance);
				result.setErrMsg(MsgConstant.getSendSuccessMsg(instance.getDestActivityChineseName(), instance.getAssigneeName()));
				//WfUtils.clearWfSendInfo(instance);
			}

			WfAction.renderJson(result);
		} catch (Exception e) {
			ResultForm result = new ResultForm(false,"发送失败！");
			WfAction.renderJson(result);
			throw e;
		}
		
		return null;
	}
	
	public String calcWfSendOption() throws Exception {
		wfService.calcWfSendOption(instance);
		this.renderJson(instance);
		return null;
	}
	
//	/**
//	 * 获取流程图
//	 */
//	public String loadProcessDefPngFile() throws Exception{
//		template = wfBusTemplateService.getByTemplateCode(template.getTemplateCode());
//		
//		//获取指定流程定义.png文件对应的Stream资源
//		InputStream in = wfService.getProcDiagramPngFileAsStream(template.getWfDefKey(), template.getWfDefVersion());
//		if(in != null){
//			//把获得的流程图对应的Stream写入到输出缓冲区
//			FileCopyUtils.copy(in, BaseAction.getResponse().getOutputStream());
//		}
//		return null;
//	}
	
	/**
	 * 设置流程实例运行时信息（包括模板编号、版本、视图、节点信息）
	 */
	private void setProcessInstanceRunInfo(){
		if(instance.getViewName() == null || instance.getViewName().trim().length() == 0){
			throw new RuntimeException("The viewName is null!");
		}
		
		//如果是待办、在办视图
		if(instance.getViewName().equals(WfActElemPrivDefForm.DB_ZB_VIEW)){
			//流程起草阶段
			if(instance.getTaskInstDbid() == null){
				wfService.setInstanceRunInfoByTemplateCode(instance, template.getTemplateCode());
			}
			else{
				wfService.setInstanceRunInfoByTaskId(instance, this.getLoginUserName());
			}
		}
		//如果已办、办结视图
		else if(instance.getViewName().equals(WfActElemPrivDefForm.YB_VIEW) || instance.getViewName().equals(WfActElemPrivDefForm.BJ_VIEW)){
			wfService.setInstanceRunInfoByWfInstancId(instance);
		}
		else{
			throw new RuntimeException("Not exist viewName: " + instance.getViewName());
		}
	}
	
	/**
	 * 根据流程权限获取FORM类型页面元素列表
	 */
	public String getFormsWithPriv() throws Exception {
		setProcessInstanceRunInfo();
		List<WfPageElementForm> list = wfBusTemplateService.getElementsWithPrivByType(WfPageElementForm.FORM_ELEM_TYPE, instance, false);
		ExtBaseAction.extRenderListJson(list, true);
		return null;
	}
	
	/**
	 * 获取FORM类型页面元素列表
	 */
	public String getForms() throws Exception {
		List<WfPageElementForm> list = wfBusTemplateService.getElementsByType(template.getTemplateCode(), WfPageElementForm.FORM_ELEM_TYPE, false);
		ExtBaseAction.extRenderListJson(list, true);
		return null;
	}
	
	/**
	 * 根据流程权限分组获取指定父元素的子元素列表
	 */
	public String getChildElementsWithPriv() throws Exception {
		setProcessInstanceRunInfo();
		List<WfPageElementForm> list = wfBusTemplateService.getChildElementsWithPriv(pageElement.getParentElementCode(), instance);
		ExtBaseAction.extRenderListJson(list, true);
		return null;
	}

	/**
	 * 获取指定父元素的子元素列表
	 */
	public String getChildElements() throws Exception {
		List<WfPageElementForm> list = wfPageElementService.getChildElements(pageElement.getParentElementCode());
		ExtBaseAction.extRenderListJson(list, true);
		return null;
	}
	
	public String getAssigneeRange() throws Exception {
		String assigneeRange = wfService.getAssigneeRange(instance.getTaskInstDbid(), instance.getDestActivityName());
		ExtBaseAction.extRenderSuccess(assigneeRange);
		return null;
	}
	
	public String saveTaskOpinion() throws Exception{
		if(this.instance != null && instance.getTaskInstDbid() != null
				&& instance.getHandleComments() != null && instance.getHandleComments().trim().length()>0){
			wfService.saveTaskOpinion(instance);
			ExtBaseAction.extRenderSuccess();
		}
		return null;
	}
	
	/**
	 * 获取历史跟踪信息
	 * @param wfBusInstanceId
	 */
	public String getTraceInfo() throws Exception{

		List<TraceRecord> list = null;
			
		if(instance.getProcInstId() != null)
			list = wfService.getTraceInfo(instance.getProcInstId());
		else if(instance.getTaskInstDbid() != null)
			list = wfService.getTraceInfo(instance.getTaskInstDbid());

		ExtResult result = new ExtResult(true, true);
		result.setResult(list);
		ExtBaseAction.renderJson(Struts2Utils.getJsonString(result, DateUtils.YYYY_MM_DD_HH_MM_SS));
		
		return null;
	}
	
	/**
	 * 任务取回
	 * @return
	 * @throws Exception
	 */
	public String takeBackTask() throws Exception{
		if(instance != null && instance.getProcInstId() != null){
			boolean success = this.wfService.takeBackTask(instance.getProcInstId(), this.getLoginUserName());
			WfUtils.renderWfTakeBackMsg(success);
		}
		return null;
	}
	
	/**
	 * 获取task的历史意见
	 * @return
	 * @throws Exception
	 */
	public String getTaskOpinion() throws Exception{
		if(instance != null && instance.getTaskInstDbid()!= null){
			String opinion = this.wfService.getTaskOpinion(instance.getTaskInstDbid());
			if(opinion != null && opinion.trim().length()>0)
				WfAction.renderText(opinion);
		}
		return null;
	}
	
	/**
	 * 回退到上一任务节点
	 */
	public String returnPrevTask() throws Exception{
		if(this.instance != null && this.instance.getTaskInstDbid() != null){
			boolean success = wfService.returnPrevTask(instance.getTaskInstDbid());
			WfUtils.renderWfReturnBackMsg(success);
		}
		return null;
	}
	
	/**
	 * 打开起草工作页面
	 * @return
	 */
	public String loadDraftWork(){
		templateTypeList = wfBusTemplateTypeService.getAllTemplates();
		return "draft-works";
	}
	
	private String getForward(String defaultForward){
		if(forward != null && forward.trim().length() > 0)
			return forward;
		else
			return defaultForward;
	}
	
	public String getForward() {
		return forward;
	}

	public void setForward(String forward) {
		this.forward = forward;
	}
	
	public WfPageElementForm getPageElement() {
		return pageElement;
	}

	public void setPageElement(WfPageElementForm pageElement) {
		this.pageElement = pageElement;
	}

	public WfBusInstanceTaskForm getInstance() {
		return instance;
	}
	
	public void setInstance(WfBusInstanceTaskForm instance) {
		this.instance = instance;
	}
	
	public WfBusTemplateForm getTemplate() {
		return template;
	}

	public void setTemplate(WfBusTemplateForm template) {
		this.template = template;
	}

	public WfBusTemplateViewConfig getViewConfig() {
		return viewConfig;
	}

	public void setViewConfig(WfBusTemplateViewConfig viewConfig) {
		this.viewConfig = viewConfig;
	}

	public Long[] getTaskInstDbids() {
		return taskInstDbids;
	}

	public void setTaskInstDbids(Long[] taskInstDbids) {
		this.taskInstDbids = taskInstDbids;
	}
	
	public String getLoadProcessDiagramUrl() {
		return loadProcessDiagramUrl;
	}
	
	public void setLoadProcessDiagramUrl(String loadProcessDiagramUrl) {
		this.loadProcessDiagramUrl = loadProcessDiagramUrl;
	}

	public Long getActInstDbid() {
		return actInstDbid;
	}

	public void setActInstDbid(Long actInstDbid) {
		this.actInstDbid = actInstDbid;
	}

	public WfActivityInstanceForm getActivityInstanceForm() {
		return activityInstanceForm;
	}

	public void setActivityInstanceForm(WfActivityInstanceForm activityInstanceForm) {
		this.activityInstanceForm = activityInstanceForm;
	}

	public List<WfBusTemplateTypeForm> getTemplateTypeList() {
		return templateTypeList;
	}

	public void setTemplateTypeList(List<WfBusTemplateTypeForm> templateTypeList) {
		this.templateTypeList = templateTypeList;
	}
	
	
}
